
package com.insigma.business.qrcode.soldier._provider.impl;

import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Sets;


import com.insigma.business.qrcode.common.dao.CommonAdminAreaDO;
import com.insigma.business.qrcode.common.dao.GovEmployeeJobDao;
import com.insigma.business.qrcode.common.dao.GovOrgDao;
import com.insigma.business.qrcode.common.service.CommonAdminAreaService;
import com.insigma.business.qrcode.common.service.GovOrgService;
import com.insigma.business.qrcode.common.service.SequenceGenerator;
import com.insigma.business.qrcode.common.util.BizCheckUtil;
import com.insigma.business.qrcode.common.util.ResponseUtils;
import com.insigma.business.qrcode.common.vo.BaseResponse;
import com.insigma.business.qrcode.soldier.dao.GovEmployeeDao;
import com.insigma.business.qrcode.soldier.dao.GovEmployeeRoleDao;
import com.insigma.business.qrcode.soldier.dto.*;
import com.insigma.business.qrcode.soldier.dto.gov.BaseProviderImpl;
import com.insigma.business.qrcode.common.template.area.ScenarioCodeEnum;
import com.insigma.business.qrcode.common.template.area.ServiceCallback;
import com.insigma.business.qrcode.soldier.entity.GovEmployeeDO;
import com.insigma.business.qrcode.soldier.entity.GovEmployeeRoleDO;
import com.insigma.business.qrcode.soldier.entity.GovOrgDO;
import com.insigma.business.qrcode.soldier.entity.GovResourceDO;
import com.insigma.business.qrcode.soldier._provider.GovEmployeeProvider;
import com.insigma.business.qrcode.common.converter.GovEmployeeProviderConverter;
import com.insigma.business.qrcode.soldier.service.GovEmployeeService;
import com.insigma.business.qrcode.soldier.service.GovResourceService;
import lombok.extern.slf4j.Slf4j;
import org.apache.logging.log4j.util.Strings;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.text.SimpleDateFormat;
import java.util.*;


@Slf4j
@Service
@Component("govEmployeeProvider")
public class GovEmployeeProviderImpl extends BaseProviderImpl implements GovEmployeeProvider {

    @Autowired
    private GovEmployeeService govEmployeeService;

    @Autowired(required = false)
    private GovEmployeeDao govEmployeeDao;

    @Autowired(required = false)
    private GovEmployeeJobDao govEmployeeJobDao;

    @Autowired(required = false)
    private GovResourceService govResourceService;

    @Autowired(required = false)
    private GovEmployeeRoleDao govEmployeeRoleDao;

    @Autowired(required = false)
    private GovOrgDao govOrgDao;

    @Autowired
    private GovOrgService govOrgService;
    @Autowired
    private CommonAdminAreaService commonAdminAreaService;

    @Autowired(required = false)
    private SequenceGenerator sequenceGenerator;


    @Override
    public BaseResponse<GovEmployeeDTO> getGovEmployeeByMobile(final String mobile) {

        final BaseResponse<GovEmployeeDTO> baseResponse = new BaseResponse<>();
        serviceTemplate.execute(baseResponse, new ServiceCallback() {
            @Override
            public void check() {
                BizCheckUtil.checkMobile(mobile);
            }

            @Override
            public void executeService() {
                final GovEmployeeDO govEmployeeDO = govEmployeeService.getByMobile(mobile);
                BizCheckUtil.checkNotNull(govEmployeeDO, "账号不存在或密码错误");
                final GovEmployeeDTO govEmployeeDTO = GovEmployeeProviderConverter.convertResponseDO2DTO(govEmployeeDO);

                CommonAdminAreaDO adminAreaOfEmployee = commonAdminAreaService.findAdminAreaOfEmployee(govEmployeeDTO.getId());
                if (adminAreaOfEmployee != null) {
                    govEmployeeDTO.setAdminAreaCode(adminAreaOfEmployee.getId());
                    govEmployeeDTO.setAdminAreaValue(adminAreaOfEmployee.getValue());
                }

                GovOrgDO govOrgDO = govOrgDao.getByEmployId(govEmployeeDTO.getId());
                if (govOrgDO != null) {
                    govEmployeeDTO.setOrgType(govOrgDO.getType());
                }

                List<GovEmployeeRoleDO> relDO = govEmployeeRoleDao.listByEmployeeId2(govEmployeeDTO.getId());

                if (!CollectionUtils.isEmpty(relDO)) {
                    Set<String> roleCode = Sets.newHashSet();
                    Set<String> roleNames = Sets.newHashSet();
                    Set<String> resourceCodeSet = Sets.newHashSet();

                    for (GovEmployeeRoleDO govEmployeeRoleDO : relDO) {
                        roleCode.add(govEmployeeRoleDO.getCode());
                        roleNames.add(govEmployeeRoleDO.getName());
                        List<GovResourceDO> govResourceDOS = govResourceService.listByRoleId(govEmployeeRoleDO.getId());
                        if (!CollectionUtils.isEmpty(govResourceDOS)) {
                            for (GovResourceDO govResourceDO : govResourceDOS) {
                                resourceCodeSet.add(govResourceDO.getCode());
                                resourceCodeSet.addAll(recursiveGetParentResource(govResourceDO));
                            }
                        }
                    }

                    govEmployeeDTO.setRoleCodes(String.join(",", roleCode));
                    govEmployeeDTO.setRoleNames(String.join(",", roleNames));
                    govEmployeeDTO.setResourceCodes(String.join(",", resourceCodeSet));

                }
                //添加sls日志打印
                String areaCode="";
                if (adminAreaOfEmployee != null) {
                    areaCode = adminAreaOfEmployee.getId();
                    areaCode=areaCode.substring(0,9);
                }
                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                String date = sdf.format(new Date());
                Logtail logtail = new Logtail(govEmployeeDTO.getId(), "政府工作人员", areaCode, 1, "",date);
                String jsonString = JSONObject.toJSONString(logtail);
                LoggerFactory.getLogger("logtail").debug(jsonString);
                ResponseUtils.setupSuccessResponse(baseResponse, govEmployeeDTO);
            }

            @Override
            public ScenarioCodeEnum getScenarioEnum() {
                return ScenarioCodeEnum.GOV_EMPLOYEE_GET_BY_MOBILE;
            }
        });
        return baseResponse;
    }

    @Override
    public BaseResponse<GovEmployeeIdDTO> getGovEmployeeIdByMobile(String mobile) {
        final BaseResponse<GovEmployeeIdDTO> baseResponse = new BaseResponse<>();
        serviceTemplate.execute(baseResponse, new ServiceCallback() {
            @Override
            public void check() {
            }

            @Override
            public void executeService() {
                final GovEmployeeIdDTO govEmployeeId = govEmployeeService.getGovEmpIdByMobile(mobile);
                BizCheckUtil.checkNotNull(govEmployeeId, "账号不存在或密码错误");
                ResponseUtils.setupSuccessResponse(baseResponse, govEmployeeId);
            }

            @Override
            public ScenarioCodeEnum getScenarioEnum() {
                return ScenarioCodeEnum.GOV_EMPLOYEE_ID_GET_BY_MOBILE;
            }
        });
        return baseResponse;
    }

    @Override
    public BaseResponse<GovEmployeeDTO> getGovEmployeeByMobileOrAccount(String mobile, String outerAccountId) {

        final BaseResponse<GovEmployeeDTO> baseResponse = new BaseResponse<>();
        serviceTemplate.execute(baseResponse, new ServiceCallback() {
            @Override
            public void check() {
            }

            @Override
            public void executeService() {
                GovEmployeeDO govEmployeeDO = govEmployeeService.getByMobile(mobile);
                if (govEmployeeDO == null) {
                    govEmployeeDO = govEmployeeService.getByEmployeeZzdAccountId(outerAccountId);
                }
                BizCheckUtil.checkNotNull(govEmployeeDO, "账号不存在或密码错误");
                final GovEmployeeDTO govEmployeeDTO = GovEmployeeProviderConverter.convertResponseDO2DTO(govEmployeeDO);

                CommonAdminAreaDO adminAreaOfEmployee = commonAdminAreaService.findAdminAreaOfEmployee(govEmployeeDTO.getId());
                if (adminAreaOfEmployee != null) {
                    govEmployeeDTO.setAdminAreaCode(adminAreaOfEmployee.getId());
                    govEmployeeDTO.setAdminAreaValue(adminAreaOfEmployee.getValue());
                }

                GovOrgDO govOrgDO = govOrgDao.getByEmployId(govEmployeeDTO.getId());
                if (govOrgDO != null) {
                    govEmployeeDTO.setOrgType(govOrgDO.getType());
                }

                List<GovEmployeeRoleDO> relDO = govEmployeeRoleDao.listByEmployeeId2(govEmployeeDTO.getId());

                if (!CollectionUtils.isEmpty(relDO)) {
                    Set<String> roleCode = Sets.newHashSet();
                    Set<String> roleNames = Sets.newHashSet();
                    Set<String> resourceCodeSet = Sets.newHashSet();

                    for (GovEmployeeRoleDO govEmployeeRoleDO : relDO) {
                        roleCode.add(govEmployeeRoleDO.getCode());
                        roleNames.add(govEmployeeRoleDO.getName());
                        List<GovResourceDO> govResourceDOS = govResourceService.listByRoleId(govEmployeeRoleDO.getId());
                        if (!CollectionUtils.isEmpty(govResourceDOS)) {
                            for (GovResourceDO govResourceDO : govResourceDOS) {
                                resourceCodeSet.add(govResourceDO.getCode());
                                resourceCodeSet.addAll(recursiveGetParentResource(govResourceDO));
                            }
                        }
                    }

                    govEmployeeDTO.setRoleCodes(String.join(",", roleCode));
                    govEmployeeDTO.setRoleNames(String.join(",", roleNames));
                    govEmployeeDTO.setResourceCodes(String.join(",", resourceCodeSet));

                }

                ResponseUtils.setupSuccessResponse(baseResponse, govEmployeeDTO);
            }

            @Override
            public ScenarioCodeEnum getScenarioEnum() {
                return ScenarioCodeEnum.GOV_EMPLOYEE_GET_BY_MOBILE;
            }
        });
        return baseResponse;
    }

    @Override
    public BaseResponse<GovEmployeeDTO> getRoles(String employeeId) {


        final GovEmployeeDO govEmployeeDO = govEmployeeService.get(employeeId);
        BizCheckUtil.checkNotNull(govEmployeeDO, "账号不存在或密码错误");
        final GovEmployeeDTO govEmployeeDTO = GovEmployeeProviderConverter.convertResponseDO2DTO(govEmployeeDO);

        List<GovEmployeeRoleDO> relDO = govEmployeeRoleDao.listByEmployeeId2(govEmployeeDTO.getId());

        if (!CollectionUtils.isEmpty(relDO)) {
            Set<String> roleCode = Sets.newHashSet();
            Set<String> resourceCodeSet = Sets.newHashSet();
            Set<String> roleNames = Sets.newHashSet();

            for (GovEmployeeRoleDO govEmployeeRoleDO : relDO) {
                roleCode.add(govEmployeeRoleDO.getCode());
                roleNames.add(govEmployeeRoleDO.getName());
                List<GovResourceDO> govResourceDOS = govResourceService.listByRoleId(govEmployeeRoleDO.getId());
                if (!CollectionUtils.isEmpty(govResourceDOS)) {
                    for (GovResourceDO govResourceDO : govResourceDOS) {
                        resourceCodeSet.add(govResourceDO.getCode());
                        resourceCodeSet.addAll(recursiveGetParentResource(govResourceDO));
                    }
                }
            }

            govEmployeeDTO.setRoleNames(String.join(",", roleNames));
            govEmployeeDTO.setRoleCodes(String.join(",", roleCode));
            govEmployeeDTO.setResourceCodes(String.join(",", resourceCodeSet));

            CommonAdminAreaDO adminAreaOfEmployee = commonAdminAreaService.findAdminAreaOfEmployee(govEmployeeDTO.getId());
            if (adminAreaOfEmployee != null) {
                govEmployeeDTO.setAdminAreaCode(adminAreaOfEmployee.getId());
                govEmployeeDTO.setAdminAreaValue(adminAreaOfEmployee.getValue());
            }
        }
        return ResponseUtils.buildSuccessResponse(govEmployeeDTO);
    }

    private Set<String> recursiveGetParentResource(GovResourceDO govResourceDO) {
        if (govResourceDO == null || Strings.isBlank(govResourceDO.getParentCode())) {
            return Sets.newHashSet();
        }

        Set<String> set = Sets.newHashSet();
        String code = govResourceDO.getParentCode();
        GovResourceDO byCode = govResourceService.getByCode(code);

        set.add(byCode.getCode());
        set.addAll(recursiveGetParentResource(byCode));

        return set;
    }

    private Set<String> recursiveGetChildResource(GovResourceDO govResourceDO) {
        if (govResourceDO == null) {
            return Sets.newHashSet();
        }

        Set<String> set = Sets.newHashSet();
        String code = govResourceDO.getCode();
        List<GovResourceDO> allChildren = govResourceService.getByParentCode(code);
        if (!CollectionUtils.isEmpty(allChildren)) {
            for (GovResourceDO allChild : allChildren) {
                set.add(allChild.getCode());
                set.addAll(recursiveGetChildResource(allChild));
            }
        }

        return set;
    }





    @Override
    public boolean checkIsAdmin(String employeeId) {
        GovEmployeeDO govEmployeeDO = govEmployeeService.get(employeeId);
        if (govEmployeeDO != null && "666666".equals(govEmployeeDO.getZzdAccountId())) {
            return true;
        }

        return false;
    }


}
